package pers.richard.ormybatis.bean.sql;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import pers.richard.ormybatis.bean.AbstractDomain;
import pers.richard.ormybatis.bean.field.FieldName;
import pers.richard.ormybatis.bean.field.IField;

/**
 * update sql参数构造器
 */
public class Update extends AbstractDomain {
	/**  查询条件构造器  */
	private Where where = Where.create();

	/**  update字段名和值  */
	private List<OperationExpressionBean> updateField = new ArrayList<OperationExpressionBean>();
	
	private Update(){}
	
	public static Update create(){
		return new Update();
	}

	public Update updateEval(CharSequence updateSql, Object... params){
		String sql = StrUtil.format(updateSql, params);
		return this.addUpdateField(new FieldName(""), "eval", sql);
	}
	
	/**
	 *	<pre>
	 *	Map map = (abc, v1)
	 *	效果同
	 *	UPDATE table SET abc = v1
	 * </pre>
	 */
	public Update updateEq(Map<String, Object> updateMap){
		if (updateMap == null || updateMap.isEmpty()) {
			return this;
		}
		for (String keyField : updateMap.keySet()) {
			Object value = updateMap.get(keyField);
			if (ObjectUtil.isEmpty(value)) {
				continue;
			}
			FieldName fieldName = new FieldName(keyField);
			this.addUpdateField(fieldName, "=", value);
		}
		return this;
	}
	
	/**
	 * 等于 (=), 忽略value空值
	 * @param updateFieldName 
	 * @param value
	 * @return
	 */
	public Update updateEq(IField Field, Object value){
		if (ObjectUtil.isEmpty(value)) {
			return this;
		}
		return this.addUpdateField(Field, "=", value);
	}
	
	/**
	 * 自增 field_name = field_name + 1
	 */
	public Update updateIncr(IField Field){
		return this.updateIncr(Field, 1);
	}
	
	/**
	 * 自增 field_name = field_name + num
	 */
	public Update updateIncr(IField Field, Number num){
		return this.addUpdateField(Field, "incr", num);
	}
	
	
	/**
	 * 自减 field_name = field_name - 1
	 */
	public Update updateReduction(IField Field){
		return this.updateIncr(Field, 1);
	}
	
	/**
	 * 自减 field_name = field_name - num
	 */
	public Update updateReduction(IField Field, Number num){
		return this.addUpdateField(Field, "reduction", num);
	}
	
	/**
	 * 设置为null
	 */
	public Update updateEqNull(IField Field){
		return this.addUpdateField(Field, "is_null", "null");
	}
	
	/**
	 * 如果value为空,则更新field = null,不忽略空值
	 * @param updateFieldName 
	 * @param value
	 * @return
	 */
	public Update updateEqNull(IField Field, Object value){
		if (ObjectUtil.isEmpty(value)) {
			return this.updateEqNull(Field);
		}
		return this.updateEq(Field, value);
	}
	
	/**
	 * 查询条件 注入sql语句  如:eval("name = 18") 或 eval("name = {}", 18) 
	 */
	public Update whereEval(CharSequence sqlTemplate, Object... params) {
		where.eval(sqlTemplate, params);
		return this;
	}
	
	/**
	 * 查询条件 等于 (=)
	 */
	public Update whereEq(IField Field, Object value) {
		where.eq(Field, value);
		return this;
	}
	
	/**
	 * 大于(>)
	 */
	public Update whereQt(IField Field, Object value) {
		where.gt(Field, value);
		return this;
	}
	
	/**
	 * 大于等于(>=) 
	 */
	public Update whereGte(IField Field, Object value) {
		where.gte(Field, value);
		return this;
	}
	
	/**
	 * 小于(<) 
	 */
	public Update whereLt(IField Field, Object value) {
		where.lt(Field, value);
		return this;
	}
	
	/**
	 * 小于等于(<=) 
	 */
	public Update whereLte(IField Field, Object value) {
		where.lte(Field, value);
		return this;
	}
	
	/**
	 * like查询(% + value + %)
	 */
	public Update whereLike(IField Field, Object value) {
		where.like(Field, value);
		return this;
	}
	
	/**
	 * like查询(value + %)
	 */
	public Update whereLikeLeft(IField Field, Object value) {
		where.likeLeft(Field, value);
		return this;
	}
	
	/**
	 * like查询(% + value)
	 */
	public Update whereLikeRight(IField Field, Object value) {
		where.likeRight(Field, value);
		return this;
	}
	
	public Where getWhere() {return where;}
	public void setWhere(Where where) {this.where = where;}

	public List<OperationExpressionBean> getUpdateField() {return updateField;}
	public void setUpdateField(List<OperationExpressionBean> updateField) {this.updateField = updateField;}

	/**
	 * 设置修改的字段和操作符
	 */
	private Update addUpdateField(IField Field,String oper, Object value) {
		updateField.add(new OperationExpressionBean(Field.toString(), oper, value));
		return this;
	}
}